package com.example.securitymode.config;

import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    // url授权:  HttpSecurity
    @Override
    protected void configure(HttpSecurity security) throws Exception {
        // 首页所有人可以访问，但是功能也只有对有权限的人可以访问
        security
                .authorizeRequests() // 认证请求
                .antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3")
        ;
        // 自带登录页面，http://localhost:8080/login
        // 定制登录页，loginPage("/toLogin")
        // 指定表单提交url：loginProcessingUrl("/user/login")
        security.formLogin().loginPage("/toLogin")
                .usernameParameter("username").passwordParameter("password")
                .loginProcessingUrl("/user/login");
        // 开启注销功能,源码http://localhost:8080/logout，并且注销成功后跳转到/的Controller
        security.logout().logoutSuccessUrl("/");
        // 版本不同问题，可能会出现注销失败，关闭csrf
        // security.csrf().disable();
        // 开启记住我功能:本质就是记住一个cookies，默认保存2周
        security.rememberMe().rememberMeParameter("remember");
    }

    // 用户认证：AuthenticationManagerBuilder
    // SpringSecurity5 以后默认需要新郑密码密码加密方式
    @Override
    public void configure(AuthenticationManagerBuilder builder) throws Exception {
        // 内存中测试数据
        builder.inMemoryAuthentication()   // SpringSecurity5 以后默认需要新郑密码密码加密方式
                .passwordEncoder(new BCryptPasswordEncoder())
                .withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1")
                .and()
                .withUser("admin1").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2", "vip3")
        ;
    }
}
